 /*******************************************************************************
  * Copyright (c) 2000, 2006 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.update.internal.core;

 import java.io.*;
 import java.net.*;
 import java.util.ArrayList ;
 import java.util.HashMap ;
 import java.util.Iterator ;
 import java.util.List ;
 import java.util.Map ;

 import org.eclipse.core.runtime.*;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.update.core.*;

 /**
  * Plugin Content Consumer on a Site
  */
 public class SiteFilePluginContentConsumer extends ContentConsumer {

     private IPluginEntry pluginEntry;
     private ISite site;
     private boolean closed = false;

     // recovery
 // temporary name to original name map
 private Map renames = new HashMap (2);

     // for abort
 private List /*of path as String */
     installedFiles;

     /*
      * Constructor
      */
     public SiteFilePluginContentConsumer(IPluginEntry pluginEntry, ISite site) {
         this.pluginEntry = pluginEntry;
         this.site = site;
         installedFiles = new ArrayList ();
     }

     /*
      * @see ISiteContentConsumer#store(ContentReference, IProgressMonitor)
      */
     public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException {
         InputStream inStream = null;
         String pluginPath = null;

         if (closed) {
             UpdateCore.warn("Attempt to store in a closed SiteFilePluginContentConsumer", new Exception ()); //$NON-NLS-1$
 return;
         }

         try {
             URL newURL = new URL(site.getURL(), Site.DEFAULT_PLUGIN_PATH + pluginEntry.getVersionedIdentifier().toString());
             pluginPath = newURL.getFile();
             String contentKey = contentReference.getIdentifier();
             inStream = contentReference.getInputStream();
             pluginPath += pluginPath.endsWith(File.separator) ? contentKey : File.separator + contentKey;

             // error recovery
 String logEntry=null;
             if ("plugin.xml".equals(contentKey)) { //$NON-NLS-1$
 logEntry=ErrorRecoveryLog.PLUGIN_ENTRY;
             } else if ("fragment.xml".equals(contentKey)) { //$NON-NLS-1$
 logEntry=ErrorRecoveryLog.FRAGMENT_ENTRY;
             } else if ("META-INF/MANIFEST.MF".equals(contentKey)) { //$NON-NLS-1$
 logEntry=ErrorRecoveryLog.BUNDLE_MANIFEST_ENTRY;
             }
             if (logEntry!=null) {
                 String originalName = pluginPath.replace(File.separatorChar, '/');
                 File localFile = new File(originalName);
                 if (localFile.exists()) {
                     throw Utilities.newCoreException(NLS.bind(Messages.UpdateManagerUtils_FileAlreadyExists, (new Object [] { localFile })), null);
                 }
                 pluginPath = ErrorRecoveryLog.getLocalRandomIdentifier(pluginPath);
                 renames.put(pluginPath, originalName);
                 ErrorRecoveryLog.getLog().appendPath(logEntry, pluginPath);
             }
             //
 UpdateManagerUtils.copyToLocal(inStream, pluginPath, null);
             UpdateManagerUtils.checkPermissions(contentReference, pluginPath); // 20305
 installedFiles.add(pluginPath);
         } catch (IOException e) {
             throw Utilities.newCoreException(NLS.bind(Messages.GlobalConsumer_ErrorCreatingFile, (new String [] { pluginPath })), e);
         } finally {
             if (inStream != null) {
                 try {
                     // close stream
 inStream.close();
                 } catch (IOException e) {
                 }
             }
         }
     }

     /*
      * @see ISiteContentConsumer#close()
      */
     public void close() throws CoreException {

         if (closed) {
             UpdateCore.warn("Attempt to close a closed SiteFilePluginContentConsumer", new Exception ()); //$NON-NLS-1$
 return;
         }

         for(Iterator it = renames.entrySet().iterator(); it.hasNext();){
             // rename file
 Map.Entry entry = (Map.Entry )it.next();
             String temporary = (String ) entry.getKey();
             String original = (String ) entry.getValue();
             ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.RENAME_ENTRY, temporary);
             File fileToRename = new File(temporary);
             boolean sucess = false;
             if (fileToRename.exists()) {
                 File renamedFile = new File(original);
                 sucess = fileToRename.renameTo(renamedFile);
             }
             if (!sucess) {
                 String msg = NLS.bind(Messages.ContentConsumer_UnableToRename, (new String [] { temporary, original }));
                 throw Utilities.newCoreException(msg, new Exception (msg));
             }
         }

         if (site instanceof SiteFile)
              ((SiteFile) site).addPluginEntry(pluginEntry);
         closed = true;
     }

     /*
      *
      */
     public void abort() throws CoreException {

         if (closed) {
             UpdateCore.warn("Attempt to abort a closed SiteFilePluginContentConsumer", new Exception ()); //$NON-NLS-1$
 return;
         }

         boolean success = true;
         InstallRegistry.unregisterPlugin(pluginEntry);

         // delete plugin manifests first
 for(Iterator it = renames.values().iterator(); it.hasNext();){
             String originalName = (String ) it.next();

             ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.DELETE_ENTRY, originalName);
             File fileToRemove = new File(originalName);
             if (fileToRemove.exists()) {
                 if(!fileToRemove.delete()){
                     String msg = NLS.bind(Messages.SiteFilePluginContentConsumer_unableToDelete, (new String [] { originalName }));
                     UpdateCore.log(msg, null);
                     success = false;
                 }
             }
         }

         if (success) {
             // remove the plugin files;
 Iterator iter = installedFiles.iterator();
             File featureFile = null;
             while (iter.hasNext()) {
                 String path = (String ) iter.next();
                 featureFile = new File(path);
                 UpdateManagerUtils.removeFromFileSystem(featureFile);
             }

             // remove the plugin directory if empty
 try {
                 URL newURL = new URL(site.getURL(), Site.DEFAULT_PLUGIN_PATH + pluginEntry.getVersionedIdentifier().toString());
                 String pluginPath = newURL.getFile();
                 UpdateManagerUtils.removeEmptyDirectoriesFromFileSystem(new File(pluginPath));
             } catch (MalformedURLException e) {
                 throw Utilities.newCoreException(e.getMessage(), e);
             }
         }
         closed = true;
     }

 }

